package net.knightwatch.kwtools;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import net.knightwatch.kwtools.customers.Building;
import net.knightwatch.kwtools.database.KwToolsDatasource;
import net.knightwatch.kwtools.walkthrough.Potential;
import net.knightwatch.kwtools.walkthrough.items.Item;
import net.knightwatch.kwtools.walkthrough.items.ItemArrayAdapter;
import net.knightwatch.kwtools.walkthrough.items.ItemType;
import utilities.PdfGenerator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;

public class PotentialActivity extends Activity {
	// Potential Edit/Create/View
	private static final String TAG = "PotentialActivity";
	private KwToolsDatasource datasource = new KwToolsDatasource(this);
	private Boolean viewPotential;
	private Potential potential = new Potential();
	private EditText potentialName;
	private Spinner buildingList;
	private EditText projectedStartDate;
	private EditText scopeOfWork;
	private CheckBox potentialComplete;
	// Potential Edit/Create mode
	private ItemArrayAdapter itemArrayAdapter;
	private ArrayList<Building> customerBuildings;
	// Potential View Only Mode
	private ListView itemListView;
	private ArrayAdapter<Building> buildingArrayAdapter;
	private AlertDialog.Builder ab;
	private ArrayList<ItemType> itemTypes = new ArrayList<ItemType>();
	private ArrayAdapter<ItemType> itemTypeAdapter;
	private Uri uri;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Check if this is to view a potential or create a new one
		viewPotential = getIntent().getBooleanExtra("readOnly", false);
		ab = new AlertDialog.Builder(this);
		if(viewPotential){
			setContentView(R.layout.potential_activity);
			lookupPotential(getIntent().getLongExtra("potentialId", -1));
			setupItemList();
		} else {
			setContentView(R.layout.potential_activity_add);
			potential = new Potential(getIntent().getLongExtra("customerId",-1));
		}
		try {
			createPotentialNameEditText();
			createBuildingSelectionSpinner();
			createPotentialStartDateEditText();
			createScopeOfWorkEditText();
			createItemTypeAlertDialog();
			// FIXME make show up in both layouts
			createCompletedCheckBox();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	private void lookupPotential(long potentialId) {
		try{
			datasource.Open();
			potential = datasource.getPotential(potentialId);
		} catch (Exception e){
			e.printStackTrace();
		} finally {
			datasource.Close();
		}
	}
	private void setupItemList() {
		itemArrayAdapter = new ItemArrayAdapter(this, R.layout.item_list_item, this.potential.getItems());
		itemListView = (ListView)findViewById(R.id.itemListView);
		itemListView.setAdapter(itemArrayAdapter);
		itemListView.setOnItemClickListener(new OnItemClickListener(){
	
			public void onItemClick(AdapterView<?> items, View view, int position,
					long id) {
				// TODO Launch the Item Detail Activity and Load answers
				Item item = (Item) items.getItemAtPosition(position);
				Intent intent = new Intent(PotentialActivity.this, ItemDetailActivity.class);
				intent.putExtra("customerId", potential.getCustomerId());
				intent.putExtra("potentialId", potential.getId());
				intent.putExtra("itemTypeId", item.getItemType().getItemTypeId());
				intent.putExtra("itemId", item.getItemId());
				Log.d(TAG, "Starting ItemDetailActivity with Extra data");
				startActivity(intent);
			}
			
		});
		itemListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){

			public void onCreateContextMenu(ContextMenu menu, View v,
					ContextMenuInfo menuInfo) {
				// Create the delete button do delete an item from the potential list. 
				menu.add("Delete").setOnMenuItemClickListener(new OnMenuItemClickListener(){

					public boolean onMenuItemClick(MenuItem item) {
						// TODO Delete the item that was pressed. 
						AdapterView.AdapterContextMenuInfo info = null;
						try {
							info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
							Item selectedItem = (Item) itemListView.getItemAtPosition(info.position);
							Log.d(TAG, "Selected Item is ID: "+selectedItem.getItemId() + " Item Type: " + selectedItem.getItemType().getName());
							PotentialActivity.this.datasource.Open();
							PotentialActivity.this.datasource.deleteItem(selectedItem.getItemId());
							new UpdateItemsTask().execute(potential.getId());
							Toast.makeText(PotentialActivity.this, "Item "+ selectedItem.getName() + " has been deleted", Toast.LENGTH_SHORT).show();
						} catch (Exception e){
							Log.e(TAG, "Error " + e.toString());
						}
						
						return false;
					}
					// Do this when the button is clicked. 
				});
				menu.add("Clone");
				
			}
			
		});
	}
	private void createCompletedCheckBox() {
		// Create the checkbox for a potential
		potentialComplete = (CheckBox) findViewById(R.id.potentialComplete_ck);
		potentialComplete.setChecked(potential.getComplete());
		potentialComplete.setOnCheckedChangeListener(new OnCheckedChangeListener(){

			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				// Change the state of the value on the potential to match the button
				potential.setComplete(isChecked);
			}
			
		});
	}
	private void createPotentialNameEditText() {
		potentialName = (EditText)findViewById(R.id.potentialName_etxt);
		potentialName.setHint("Please enter short name of potential");
		potentialName.setText(potential.getName());
		// Capture what is input for the potential name. 
		potentialName.addTextChangedListener(new TextWatcher(){
			// Set the name of the potential when the text changes
			public void afterTextChanged(Editable s) {
				potential.setName(s.toString());					
			}

			public void beforeTextChanged(CharSequence s, int start,
					int count, int after) {
			}

			public void onTextChanged(CharSequence s, int start,
					int before, int count) {
			}
			
		});
		
	}
	private void createScopeOfWorkEditText() {
		scopeOfWork = (EditText) findViewById(R.id.scopeOfWork_etxt);
		scopeOfWork.setHint("Please enter a detailed scope of work for the potential");
		scopeOfWork.setText(potential.getScopeOfWork());
		scopeOfWork.addTextChangedListener(new TextWatcher(){

			public void afterTextChanged(Editable arg0) {
				// Set the scope of work text to what was entered in the edit text .
				potential.setScopeOfWork(arg0.toString());
			}

			public void beforeTextChanged(CharSequence s, int start,
					int count, int after) {
				// not used
				
			}

			public void onTextChanged(CharSequence s, int start,
					int before, int count) {
				// not used
				
			}
			
		});
	}
	private void createPotentialStartDateEditText() {
		projectedStartDate = (EditText)findViewById(R.id.projectedStartDate_etxt);
		SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
		formatter.setLenient(false);
		Date potentialStartDate = new Date(System.currentTimeMillis());
		if(potential.getMsProjectedStartDate() > 0){
			potentialStartDate.setTime(potential.getMsProjectedStartDate());
		}
		projectedStartDate.setText(formatter.format(potentialStartDate));
		// Add DatePickerDialog
		projectedStartDate.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				// TODO Auto-generated method stub
				final Calendar c = Calendar.getInstance();
				if(PotentialActivity.this.potential.getMsProjectedStartDate() > 0){
					c.setTimeInMillis(PotentialActivity.this.potential.getMsProjectedStartDate());
				}
				
				new DatePickerDialog(PotentialActivity.this, new DatePickerDialog.OnDateSetListener() {
					public void onDateSet(DatePicker view, int year, int monthOfYear,
							int dayOfMonth) {
						// TODO Auto-generated method stub
						String dateString = (monthOfYear + 1) + "/" + dayOfMonth + "/" + year;
						SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
						formatter.setLenient(false);
						Date newDate = new Date();
						try {
							newDate = formatter.parse(dateString);
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						PotentialActivity.this.potential.setMsProjectedStartDate(newDate.getTime());
						PotentialActivity.this.projectedStartDate.setText(formatter.format(newDate));						
					}
				}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)).show();
			}
			
			
		});
		
		
	}
	private void createBuildingSelectionSpinner() {
		buildingList = (Spinner)findViewById(R.id.building_spinner);
		customerBuildings = new ArrayList<Building>();
		//Add a listener to the spinner of buildlings
		buildingArrayAdapter = new ArrayAdapter<Building>(this, android.R.layout.simple_spinner_dropdown_item, customerBuildings);
		buildingList.setAdapter(buildingArrayAdapter);
		// Set the selected index to a previous value.
		
		buildingList.setOnLongClickListener(new OnLongClickListener(){
			public boolean onLongClick(View v) {
				// TODO Auto-generated method stub
				Log.v(TAG, "Launching the New Building Activity");
				Intent intent = new Intent(PotentialActivity.this, BuildingActivity.class);
				intent.putExtra("readOnly", false);
				intent.putExtra("customerId", potential.getCustomerId());
				intent.putExtra("potentialId", potential.getId());
				startActivity(intent);
				return false;
			}
		});
		buildingList.setOnItemSelectedListener(new OnItemSelectedListener(){
			public void onItemSelected(AdapterView<?> adapter, View arg1,
					int position, long arg3) {
				// Set the bulding ID after it is selected from the spinner
				Building building = new Building();
				building = (Building) adapter.getItemAtPosition(position);
				Log.d(TAG, "Setting building ID to " + building.getId());
				potential.setBuildingId(building.getId());
			}
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});
		
	}
	private class UpdateBuildingsTask extends AsyncTask<Long, Void, Void>{

		@Override
		protected Void doInBackground(Long... params) {
			// TODO Auto-generated method stub
			long customerId = params[0];
			try{
				datasource.Open();
				customerBuildings.clear();
				for (Building b : datasource.getCustomerBuildings(customerId)){
					customerBuildings.add(b);
				}	
			} catch (Exception e){
				e.printStackTrace();
				Log.e(TAG, "Unable to retrieve the list of customers buildings");
			} finally{
				Log.d(TAG, "Retrieved list of buildings for the customer");
				datasource.Close();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// Update the UI building list
			super.onPostExecute(result);
			Log.d(TAG, "Updating the list of buildings");
			buildingArrayAdapter.notifyDataSetChanged();
			for(int index = 0; index < customerBuildings.size(); index++){
				if(customerBuildings.get(index).getId() == potential.getBuildingId()){
					Log.d(TAG, "Setting building index to building id: " + index);
					buildingList.setSelection(index);
				}
			}
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			Log.v(TAG, "Starting task to update list of buildings");
		}
		
	}
	private class UpdateItemsTask extends AsyncTask<Long, Void, Void> {
	        
	        protected void onPreExecute() {
	            Log.d(TAG, "UpdateItemsTask - onPreExecute()");
	            Toast.makeText(PotentialActivity.this, "Loading Potential Items" , Toast.LENGTH_SHORT).show();
	        }

	        protected Void doInBackground(Long ... obj) {
	        	long value = obj[0];
	        	try{
	            	datasource.Open();
	            	potential.getItems().clear();
	            	Log.d(TAG, "Cleared potential items list - " + potential.getItems().size());
	            	for(Item i : datasource.getPotentialItems(value)){
	            		potential.addItem(i);
	            	}
	            	Log.d(TAG, "Number of items on potential: " + potential.getItems().size());
	            	Log.d(TAG, "Asynctask - Refreshing the list of items in a potential");
	            } catch (Exception e){
	            	Log.e(TAG, "Unable to retrieve a list of items for the potential");
	            	e.printStackTrace();
	            } finally {
	            	datasource.Close();
	            }
	            return null;
	        }

	        protected void onPostExecute(Void unused) {
	            Log.d(TAG, "Notifiying ItemArrayAdapter DataSetChanged");
	            itemArrayAdapter.notifyDataSetChanged();
	        }
	    }
	private class DisplayItemTypesTask extends AsyncTask<String, Void, Void>{

		@Override
		protected Void doInBackground(String... params) {
			// TODO Lookup the list of item types to return to the adapter of the item type chooser
			datasource.Open();
			try{
				// Query the database
				Log.v(TAG, "Updating the item types list");
				itemTypes.clear();
				for(ItemType itemType : datasource.getItemTypes()){
					itemTypes.add(itemType);
				}
			} catch (Exception e){
				e.printStackTrace();
			}
			datasource.Close();
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Log.i(TAG, "Adding an item to the potential");
    		// Show dialog box with the options of different types of items to add
			itemTypeAdapter.notifyDataSetChanged();
    		ab.show();
		}		
		 
	 }

	private void createItemTypeAlertDialog() {
		itemTypeAdapter = new ArrayAdapter<ItemType>(this, android.R.layout.select_dialog_singlechoice, itemTypes);
		ab.setTitle(R.string.CHOOSE_ITEM_TYPE);
 		ab.setAdapter(itemTypeAdapter, new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					Log.d(TAG, "Item Added as " + itemTypeAdapter.getItem(which));
					// Start the new intent to add a item
					ItemType itemType = (ItemType) itemTypeAdapter.getItem(which);
					Intent intent = new Intent(PotentialActivity.this, ItemDetailActivity.class);
					intent.putExtra("itemTypeId", itemType.getItemTypeId());
					intent.putExtra("customerId", potential.getCustomerId());
					intent.putExtra("potentialId", potential.getId());
					startActivity(intent);
				}
				
				
			});
		}
	@Override
	protected void onResume() {
		super.onResume();
		Log.d(TAG, "onResume()");
		new UpdateBuildingsTask().execute(potential.getCustomerId());
		if(potential.getId() > 0){
			new UpdateItemsTask().execute(potential.getId());
		}
	}
	// Create the options menu in the action bar
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu dependent on the mode.
		MenuInflater inflater = getMenuInflater();
		if (viewPotential){
			inflater.inflate(R.menu.potential_menu, menu);
		} else {
			inflater.inflate(R.menu.potential_add_menu, menu);
		}
		return true;
	}
	// What to do when one of the options menus items in the action bar is pressed.
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case R.id.save:
	    	Log.i(TAG, "Saving the potential to the customer");
	    	// FIXME Potential Activity needs a save button to update the potential details
			savePotential();
	        // Exit the activity
	        finish();
	        return true;
	    case R.id.sendPotential:
	    	Log.i(TAG,"Sending the potential via Email as a PDF");
			sharePotential(potential);
	    	return true;
	    case R.id.addItem:
	    	new DisplayItemTypesTask().execute("");
	    	return true;
	    }
		return true;
	}
	    
	private void savePotential() {
		try {
			// Try to save the potential to the customer in the database.
			datasource.Open();
			if(potential.getId() > 0){
				// TODO Update the potential in the database
				datasource.updatePotential(potential);
			} else {
				// Insert a new Potential into the database
				potential = datasource.createPotential(potential);
			}
			Log.d(TAG, "Potential Saved");
		}
		catch (Exception e){
			Log.e(TAG, "Error saving the potential to the customer record " + e);
		} finally {
			datasource.Close();
		}
	}
	private void sharePotential(Potential potential) {
		// Start a new task to create the PDF document
		new SharePotentialTask().execute(potential);
	}
	private class SharePotentialTask extends AsyncTask<Potential, Void, Void>{
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Toast.makeText(PotentialActivity.this, "Generating Potential PDF Please Wait", Toast.LENGTH_LONG).show();
		}

		@Override
		protected Void doInBackground(Potential... params) {
			Potential potential = (Potential) params[0];
			uri = PdfGenerator.createPotentialPDF(potential.getId(), PotentialActivity.this);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			Log.i(TAG, "Adding an item to the potential");
			// Lookup stuff in database if needed. 
			datasource.Open();
    		// Show dialog box with the options of different types of items to add
			Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
			sharingIntent.setType("application/pdf");
			String shareBody = "This message has been autogenerated by the version "
					//FIXME Need to pull value of version from the string resource.
					+ " 1.2 "
					+ " of  the Knight Watch sales android app."
					+ "This document contains information regarding the walkthru for "
					+ datasource.getCustomer(potential.getCustomerId()).getCustomerName() + ".";			
			sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, potential.getName() + " - " + datasource.getCustomer(potential.getCustomerId()).getCustomerName() + " - WalkThough");
			sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
			sharingIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[]{"engineering@knightwatch.net"});
			sharingIntent.putExtra(android.content.Intent.EXTRA_STREAM,uri);
			datasource.Close();
			startActivity(Intent.createChooser(sharingIntent, "Share via"));
		}		
		 
	 }


}
